/*
*文本编辑器项目
*
*
*/
#include "textedit.h"
#include <QMenuBar>//菜单栏-添加菜单用
#include <QMenu>//菜单类
#include <QAction>//菜单项-对应实际功能
#include <QLabel>//显示信息的控件-静态文本框
#include <QStatusBar>//显示打开路径的状态栏
#include <QToolBar>//工具栏
#include <QTextEdit>//文本框控件
#include <QString>//QT字符串
#include <malloc.h>//C语言堆区申请空间所需
#include <QDebug>//打印所需
#include <QDockWidget>
#include <QFile>//QT文件
#include <QByteArray>//QT数组
#include <QMessageBox>//弹出消息提示框
#include <QFileDialog>//文件对话框-获取单个文件夹路径
#include <QDir>//用来操作路径名及底层文件系统
#include <QTextCharFormat>//设置字体信息
//#include <QApplication>
#include <iostream>

#include "header.h"
#include "formnew_01.h"
extern Formnew_01 *pmid;

QString midstr;
char *arr = NULL;
QTextEdit *ptextedit;

textEdit::textEdit(QWidget *parent) : QMainWindow(parent)
{

    //设置主界面的大小
    this->resize(400, 500);
    //实例化菜单栏--用来放置【一级】_实例化菜单
    QMenuBar * pMenuBar = new QMenuBar(this);
    //实例化菜单栏插入主界面窗体中
    this->setMenuBar(pMenuBar);



    //【一级】_实例化菜单
    QMenu * pfile = new QMenu(this);
    pfile->setTitle("菜单");
    //实例化编辑
    QMenu * pedit = new QMenu("编辑",this);

    QMenu * pback = new QMenu("窗体",this);

    pMenuBar->addMenu(pfile);
    pMenuBar->addMenu(pedit);
    pMenuBar->addMenu(pback);



    //【二级】_为【一级_菜单】添加‘n个’菜单功能选项
    //Actions可以被添加到菜单和工具栏中
    QAction * paction = new QAction("打开", this);
    pfile->addAction(paction);//把二级菜单选项添加进一级菜单[pfile]中
    paction->setShortcut(QKeySequence(tr("Ctrl+O")));//设置二级菜单选项的快捷键

    pfile->addSeparator();//在【打开、保存】两个菜单选项间添加一个划线

    QAction * paction1 = new QAction("保存", this);
    pfile->addAction(paction1);
    paction1->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_S));

    pfile->addSeparator();//添加一个划线

    QAction * paction2 = new QAction("对齐方式", this);
    pfile->addAction(paction2);


    //【二级】_为【一级_编辑】添加‘n个’菜单功能选项
    QAction * paction5_color = new QAction("字体颜色", this);
    pedit->addAction(paction5_color);
    paction5_color->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_U));

    QAction * paction6_back = new QAction("返回上个界面", this);
    pback->addAction(paction6_back);
    paction6_back->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_0));


    //三级菜单
    QMenu *pnew1 = new QMenu(this);
    //QList以链表形式存储一组元素。默认为空链表，我们可以使用<<操作符添加元素
    QList<QAction *> childActionList;

    QAction * text_left = new QAction("左对齐", this);
    QAction * text_right = new QAction("右对齐", this);
    QAction * text_center = new QAction("中间对齐", this);

    childActionList << text_left << text_right << text_center;
    //将三级功能选项添加进二级菜单中--pnew1插进功能【"对齐方式"】中
    pnew1->addActions(childActionList);
    paction2->setMenu(pnew1);



    pfile->addSeparator();//添加一个划线

    QAction * paction3 = new QAction("关闭", this);//关闭文本编辑器
    pfile->addAction(paction3);
    paction3->setShortcut(QKeySequence(tr("Ctrl+i")));

    QAction * paction4_save_As = new QAction("另存为", this);//关闭文本编辑器
    pfile->addAction(paction4_save_As);
    paction4_save_As->setShortcut(QKeySequence(tr("Ctrl+u")));





    //添加二级菜单选项对应的图片
    QPixmap pmap;//临时对象
    pmap.load(":/image/Open.ico");//添加对应路径下的图片名字
    paction->setIcon(QIcon(pmap));//设置图片

    QPixmap pmap1;
    pmap1.load(":/image/Save.ico");
    paction1->setIcon(QIcon(pmap1));

    QPixmap pmap2;
    pmap2.load(":/image/justify.png");
    paction2->setIcon(QIcon(pmap2));

    QPixmap pmap3;
    pmap3.load(":/image/Close.ico");
    paction3->setIcon(QIcon(pmap3));

    QPixmap pmp4;
    pmp4.load(":/image/New.ico");
    paction4_save_As->setIcon(QIcon(pmp4));

    QPixmap pmp5;
    pmp5.load(":/image/left.png");
    text_left->setIcon(QIcon(pmp5));

    QPixmap pmp6;
    pmp6.load(":/image/right.png");
    text_right->setIcon(QIcon(pmp6));

    QPixmap pmp7;
    pmp7.load(":/image/justify.png");
    text_center->setIcon(QIcon(pmp7));

    QPixmap pmp8;
    pmp8.load(":/image/rising.svg");
    paction6_back->setIcon(QIcon(pmp8));


    //状态栏-19：36
    QStatusBar *ptatusBar = new QStatusBar(this);

    this->setStatusBar(ptatusBar);

    QLabel *plab = new QLabel(this);//在文本编辑器下方显示打开文件路径信息-给[状态栏]设置一个标签
    plab->setText("左对齐信息");

    ptatusBar->addWidget(plab);//靠左边放置
    //ptatusBar->addPermanentWidget(plab);//靠右边放置


    //工具栏--编辑器上方顶部
    QToolBar *poolbar = new QToolBar(this);
    this->addToolBar(poolbar);
    //添加二级菜单选项到工具栏上
    poolbar->addAction(paction);
    poolbar->addAction(paction1);
    poolbar->addAction(paction2);
    poolbar->addAction(paction3);
    poolbar->addAction(paction4_save_As);
    //poolbar->addAction():
    //静止悬浮
    poolbar->setFloatable(false);
    //限制在顶部和左侧悬浮
    poolbar->setAllowedAreas(Qt::TopToolBarArea | Qt::LeftToolBarArea );



    //行编辑器
    //先需要【文本编辑器】-textedit
    ptextedit = new QTextEdit(this);
    this->setCentralWidget(ptextedit);//作为中心控件使用

    //①、与二级菜单选项【保存】-通过信号链接起来
    connect(paction, &QAction::triggered, this,[=](){
       QString midfile1 = QFileDialog::getOpenFileName();

       plab->setText(midfile1);//文本编辑器下方，显示打开文件路径信息
       ptextedit->clear();

       //拿到文件路径，将文件中的内容全部拿到文本编辑器中
       std::string str1 = midfile1.toStdString();
       char *chstr = (char *)str1.c_str();

       FILE *fp;
       fp = fopen(chstr, "r+");
       if(fp == NULL)
       {
           perror("fopen error");
       }
       else
       {
           fseek(fp, 0,SEEK_END);
           int len = 0;
           len = ftell(fp);//读取文件中的字节数
           rewind(fp);
           arr = (char *)malloc(sizeof(char *) * (len +1));
           if(arr == NULL)
           {
               perror("arr = null");
               fclose(fp);
           }
           else
           {
               fread(arr, len, 1, fp);
               fclose(fp);
           }
           std::string strstr = arr;
           midstr = QString::fromStdString(strstr);

           ptextedit->setText(midstr);//将文件内容显示到文本编辑器中

       }


    });

    //②、将文本编辑器中的内容保存到另一个文件中
    connect(paction1, &QAction::triggered, this,[=](){
        QMessageBox msgbox;
        QString saveFileName = QFileDialog::getSaveFileName();
        plab->setText(saveFileName);

#if 0
        if(saveFileName.isEmpty())
        {
            perror("fopen text isEmpty!!!");
            //this->saveAsFileSlots();
        }
        //将获取到的文件路径QString类型转换成普通字符串
        std::string str = saveFileName.toStdString();
        char *chstr = (char *)str.c_str();
        cout << "存放的文件路径：" << chstr << endl;
        FILE *fp = fopen(chstr, "rb");

        //midstr是全局变量，保存文本编辑框中的QString内容
        //将QString内容->转换成普通字符串
        //方便写文件
        std::string str2 =  midstr.toStdString();
        char *chstr2 = (char *)str2.c_str();

        if(fp == NULL)
        {
            perror("fopen error");
        }
        else
        {
            qDebug() <<"向文件写当前文本编辑器中的内容" << endl;
            qDebug() <<chstr2 << endl;
            int len = sizeof(chstr2);
            fwrite(chstr2, len, 1, fp);
        }
#endif

#if 1
        //弹出消息提示框，给与三个选项进行操作点击，不同点击对应不同结果
        int ret = QMessageBox::question(this,"保存","请选择是否保存当前文本编辑框中的内容？",\
                                        QMessageBox::Yes|QMessageBox::No|\
                                        QMessageBox::Cancel);
        if(QMessageBox::Yes == ret)
        {
          //点击确定，就进入保存操作
          if(saveFileName.isEmpty())//判断文件路径是否为空
          {
              perror("fopen isEmpty");

          }
          else
          {

              QFile *file = new QFile;
              file->setFileName(saveFileName);
              bool ok = file->open(QIODevice::WriteOnly);

              if(ok)
              {
                  qDebug() <<"向文件写当前文本编辑器中的内容" << endl;
                  QString text =  ptextedit->toPlainText();
                  QByteArray arr;
                  arr.append(text);
                  file->write(arr);
                  file->close();

              }

              //用户必须单击OK按钮来取消消息框。在消息框被取消之前，GUI的其余部分将被阻塞
              msgbox.setText("保存到当前文件成功");
              msgbox.exec();
          }
        }
        else if(QMessageBox::No == ret)
        {

           msgbox.setText("不保存到当前文件，退出");
           msgbox.exec();
        }
        else
        {
            msgbox.setText("不保存就关闭文本编辑器");
            msgbox.exec();
            this->close();
        }

#endif
    });


    //③、paction4--【关闭】文本编辑器
    connect(paction3, &QAction::triggered, this, [=](){
            this->close();
    });


    //④、paction4_save_As--【另存为】
    //弹出的标题："save a file"
    //文件名是‘当前文件所在路径’+"untitiled.txt"
    //格式是：text files(*.txt)
    connect(paction4_save_As, &QAction::triggered, this, [=](){
        QString saveAsfile = QFileDialog::getSaveFileName(this, "save a file",\
                           QDir::currentPath() + "untitiled.txt", "text files(*.txt)");

        plab->setText(saveAsfile);

        if(!ptextedit->toPlainText().isEmpty())
        {
            QFile *file = new QFile;
            file->setFileName(saveAsfile);
            bool ok = file->open(QIODevice::WriteOnly);//只写打开文件

            if(ok)
            {
                //使用了QT自带文件流的操作
                QTextStream out(file);
                out << ptextedit->toPlainText();
                file->close();
            }
        }

    });


    //QDockWidget *pdock = new  QDockWidget(this);

    //左、右、中对其
    connect(text_left, &QAction::triggered, this, &textEdit::leftSlot);
    connect(text_right, &QAction::triggered, this, &textEdit::rightSlot);
    connect(text_center, &QAction::triggered, this, &textEdit::centerSlot);

    connect(paction5_color, &QAction::triggered, this, &textEdit::setcolor);

    //给【界面1】发送信号，返回【界面1】
    connect(paction6_back, &QAction::triggered, this, [=](){
        emit this->back_page3();
    });

}

void textEdit::leftSlot()
{
    if(Qt::AlignLeft == ptextedit->alignment())
    {
        return;
    }
    //把当前文本编辑框中的数据左对齐
    ptextedit->setAlignment(Qt::AlignLeft);
}

void textEdit::centerSlot()
{
    if(Qt::AlignCenter == ptextedit->alignment())
    {
        return;
    }
    ptextedit->setAlignment(Qt::AlignCenter);
}

void textEdit::rightSlot()
{
    if(Qt::AlignRight == ptextedit->alignment())
    {
        return;
    }
    ptextedit->setAlignment(Qt::AlignRight);
}

void textEdit::setcolor()
{
    QTextCharFormat fmt;
}
